﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using SharedUtils;

namespace SceneEditor
{
    public partial class SceneEditorForm : UserControl
    {
        public static Util util;

        public static System.Drawing.Color g_BackgroundColor = System.Drawing.Color.White;
        public static System.Drawing.Color g_CameraRectColor = System.Drawing.Color.Black;
        public static Entity selected_entity = null;
        public static Camera2d selected_camera = null;
        public static List<string> tagList = new List<string>();
        
        public static float Height, Width;

        TreeNode tree_Entities, tree_Cameras, tree_Sounds;

        public SceneEditorForm(Util utils)
        {
            InitializeComponent();
            util = utils;
            foreach(TreeNode n in treeView1.Nodes)
            {
                if(n.Text.Equals("Entities"))
                    tree_Entities = n;
                if (n.Text.Equals("Cameras"))
                    tree_Cameras = n;
                if (n.Text.Equals("Sounds"))
                    tree_Sounds = n;
            }

            Deserialize(utils);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            shaderGraph.form = this;

            //Init OFD's
            ofd_Sound.Multiselect = true;
            ofd_Sound.Filter = "Sound Files(*.WAV)|*.WAV|All files (*.*)|*.*";

            ofd_Entities.Multiselect = true;
            ofd_Entities.Filter = "Image Files(*.JPG;*.PNG)|*.JPG;*.PNG|All files (*.*)|*.*";

            foreach (TreeNode item in treeView1.Nodes)
            {
                if(item.Text.Equals("Entities"))
                {
                    tree_Entities = item;
                }
                else if (item.Text.Equals("Cameras"))
                {
                    tree_Cameras = item;
                }
                else if (item.Text.Equals("Sounds"))
                {
                    tree_Sounds = item;
                }
            }
        }

        public void Serialize()
        {
            //Handle this somehow (Christian might have a specific way).
        }

        public void Deserialize(Util util)
        {
            SceneEditorForm.util = util;


            foreach (TreeNode item in treeView1.Nodes)
            {
                item.Nodes.Clear();
            }

            TreeNode t;
            foreach (var item in util.entities)
            {
                if(item is SoundEntity)
                {
                    t = new TreeNode();
                    t.Text = item.name;
                    tree_Sounds.Nodes.Add(item.name);
                }
                else if(item is PictureEntity)
                {
                    t = new TreeNode();
                    t.Text = item.name;
                    tree_Entities.Nodes.Add(item.name);
                }
            }

            foreach (var item in util.cameras)
            {
                t = new TreeNode();
                t.Text = item.name;
                tree_Cameras.Nodes.Add(item.name);
            }

            treeView1.ExpandAll();
        }

        private void shaderGraph_MouseClick(object sender, MouseEventArgs e)
        {
            //Handle if need be.
        }

        private void setBackgroundColorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult dr = colorDialog1.ShowDialog();
            if(dr == DialogResult.OK)
            {
                g_BackgroundColor = colorDialog1.Color;
            }
        }

        private void addEntityToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult dr = ofd_Entities.ShowDialog();
            if (dr == DialogResult.OK)
            {
                string filename = ofd_Entities.FileName;
                if (!Path.GetExtension(filename).Equals(".png") && !Path.GetExtension(filename).Equals(".jpg"))
                {
                    return;
                }

                string name = getNewName(Path.GetFileNameWithoutExtension(filename));
                PictureEntity pe = new PictureEntity(name, new Vector2(0, 0), Path.GetFullPath(filename), new Vector2(1, 1));
                tree_Entities.Nodes.Add(Path.GetFileNameWithoutExtension(name));
                tagList.Add(name);
                util.entities.Add(pe);
            }

             treeView1.ExpandAll();
        }

        private void addCameraToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string cameraName = getNewName("Camera");
            Camera2d camera = new Camera2d();
            camera.name = cameraName;
            util.cameras.Add(camera);
            tree_Cameras.Nodes.Add(new TreeNode(camera.name));
            tagList.Add(camera.name);

            treeView1.ExpandAll();
        }

        private void addSoundToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult dr = ofd_Sound.ShowDialog();
            if (dr == DialogResult.OK)
            {
                string filename = ofd_Sound.FileName;
                if(!filename.EndsWith(".wav"))
                {
                    return;
                }

                SoundEntity se = new SoundEntity(Path.GetFullPath(filename));
                tree_Sounds.Nodes.Add(Path.GetFileNameWithoutExtension(se.name));
                tagList.Add(se.name);
                util.entities.Add(se);
            }
            treeView1.ExpandAll();
        }

        private void renameToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode node = treeView1.SelectedNode;
            if (node.Parent == null)
                return;

            RenameDialog dialog = new RenameDialog();
            dialog.Show();

            bool hasFinished = false;
            while(!hasFinished)
            {
                hasFinished = dialog.hasFinished;
                Application.DoEvents();
            }

            string newName = dialog.RenameValue;
            if(node.Parent.Text.Equals("Sounds") || node.Parent.Text.Equals("Entities"))
            {
                foreach (var item in util.entities)
                {
                    if(node.Text.Equals(item.name))
                    {
                        item.name = newName;
                    }
                }
            }
            else if(node.Parent.Text.Equals("Cameras"))
            {
                foreach (var item in util.cameras)
                {
                    if (node.Text.Equals(item.name))
                    {
                        item.name = newName;
                    }
                }
            }
            
            node.Text = newName;
            dialog.Dispose();
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode node = treeView1.SelectedNode;
            //Make sure it is not a header node.
            if(node.Parent == null)
            {
                return;
            }

            if (node.Parent.Text.Equals("Sounds") || node.Parent.Text.Equals("Entities"))
            {
                List<Entity> entitiesToRemove = new List<Entity>();
                foreach (var item in util.entities)
                {
                    if (node.Text.Equals(item.name))
                    {
                        entitiesToRemove.Add(item);
                    }
                }
                foreach (var item in entitiesToRemove)
                {
                    util.entities.Remove(item);
                }
            }
            else if (node.Parent.Text.Equals("Cameras"))
            {
                List<Camera2d> camerasToRemove = new List<Camera2d>();
                foreach (var item in util.cameras)
                {
                    if (node.Text.Equals(item.name))
                    {
                        camerasToRemove.Add(item);
                    }
                }
                foreach (var item in camerasToRemove)
                {
                    util.cameras.Remove(item);
                }
            }
            

            //Delete it.
            node.Remove();

            
        }

        private void trueToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode node = treeView1.SelectedNode;
            //Make sure it is not a header node.
            if (node.Parent == null ||
                node.Parent.Text.Equals("Cameras") ||
                node.Parent.Text.Equals("Sounds"))
            {
                return;
            }

            Entity ent = getEntity(node.Text);
            ent.isVisible = true;
        }

        private void falseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode node = treeView1.SelectedNode;
            //Make sure it is not a header node.
            if (node.Parent == null || 
                node.Parent.Text.Equals("Cameras") || 
                node.Parent.Text.Equals("Sounds"))
            {
                return;
            }

            Entity ent = getEntity(node.Text);
            ent.isVisible = false;
        }

        //Helper Methods
        public string getNewName(string tag)
        {
            uint count = 0;
            char[] num_array = new char[10] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
            tag = tag.TrimEnd(num_array);
            string new_entity_name = tag;
            while (tagList.Contains(new_entity_name))
            {
                new_entity_name = tag + count.ToString();
                count++;
            }
            return new_entity_name;
        }

        public PictureEntity getEntity(string name)
        {
            foreach (var item in util.entities)
            {
                if (item is PictureEntity && name.Equals(item.name))
                {
                    return (PictureEntity)item;
                }
            }
            return null;
        }

        public Camera2d getCamera(string name)
        {
            foreach (var item in util.cameras)
            {
                if (name.Equals(item.name))
                {
                    return item;
                }
            }
            return null;
        }

        public SoundEntity getSound(string name)
        {
            foreach (var item in util.entities)
            {
                if (item is SoundEntity && name.Equals(item.name))
                {
                    return (SoundEntity)item;
                }
            }
            return null;
        }

        public Entity getGenericEntity(string name)
        {
            foreach (var item in util.entities)
            {
                if (name.Equals(item.name))
                {
                    return item;
                }
            }
            return null;
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if(e.Node.Parent == null)
                return;

            selected_entity = null;
            selected_camera = null;

            if(e.Node.Parent.Text.Equals("Entities") || e.Node.Parent.Text.Equals("Sounds"))
            {
                selected_entity = getGenericEntity(e.Node.Text);
            }
            else if (e.Node.Parent.Text.Equals("Cameras"))
            {
                selected_camera = getCamera(e.Node.Text);
            }
        }

        private void treeView1_KeyPress(object sender, KeyPressEventArgs e)
        {
            e.Handled = true;
        }

        private void treeView1_KeyDown(object sender, KeyEventArgs e)
        {
            e.Handled = true;
        }

        private void treeView1_KeyUp(object sender, KeyEventArgs e)
        {
            e.Handled = true;
        }
    }
}
